/**
 * This file is part of the CAKIS project.
 * 
 * Copyright (c) 2009-2010 - Florian Arndt, Christian Kerl
 * 
 * @license GNU Lesser General Public License v3 <http://www.opensource.org/licenses/lgpl-3.0.html>
 * @since   01.03.2010
 * @version SVN: $Id: SOAPRequestHandler.java 120 2010-05-11 20:11:01Z christian-kerl@web.de $
 */

package org.cakis.server.service.util;

import javax.servlet.http.HttpServletRequest;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.jboss.seam.contexts.ServletLifecycle;


/**
 * SOAPRequestHandler extends the Seam SOAPRequestHandler to process outgoing messages to
 * remove the <soap:header> tag to work around bugs in JavaME SOAP implementation.
 * ATTENTION: This disables the ConversationId feature of Seam!
 * 
 * @author Christian Kerl
 */
public class SOAPRequestHandler extends org.jboss.seam.webservice.SOAPRequestHandler {

    @Override
    public boolean handleOutbound(MessageContext messageContext) {
        boolean result = super.handleOutbound(messageContext);

        return handle(result, messageContext);
    }

    @Override
    public boolean handleFault(MessageContext messageContext) {
        boolean result = super.handleFault(messageContext);

        return handle(result, messageContext);
    }

    @Override
    public void close(MessageContext messageContext) {
        HttpServletRequest request = (HttpServletRequest) messageContext.get(MessageContext.SERVLET_REQUEST);

        ServletLifecycle.endRequest(request);

        /*
         * Causes NPE in Lifecycle(Line:282), feedback: http://seamframework.org/Community/StatefulWebserviceSessionManagementIssue
         * 
        if(!request.isRequestedSessionIdValid()) {
            ServletLifecycle.endSession(request.getSession());
        }
         */
        super.close(messageContext);
    }

    private boolean handle(boolean success, MessageContext ctx) {
        if(success) {
            try {
                removeSOAPHeaderTag(ctx);
            } catch (SOAPException e) {
                success = false;
            }
        }

        return success;
    }

    private void removeSOAPHeaderTag(MessageContext ctx) throws SOAPException {
        SOAPMessageContext smc = (SOAPMessageContext) ctx;
        SOAPHeader header = smc.getMessage().getSOAPHeader();

        if(header != null) {
            header.detachNode();
        }
    }
}
